package com.codemart.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.codemart.constant.JwtHeaderConstant;
import com.codemart.constant.MessageConstant;
import com.codemart.constant.ProjectDetailConstant;
import com.codemart.constant.ProjectWebStatusCodeConstant;
import com.codemart.dto.*;
import com.codemart.exception.BaseException;
import com.codemart.exception.ProjectDetailException;
import com.codemart.exception.LoginFailedException;
import com.codemart.mapper.ProjectMapper;
import com.codemart.service.ProjectService;
import com.codemart.util.JwtUtil;
import com.codemart.vo.ProjectInfoVO;
import io.jsonwebtoken.Claims;
import io.netty.util.internal.StringUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.time.format.DateTimeFormatter;

@Service
public class ProjectServiceImpl implements ProjectService {

    @Autowired
    ProjectMapper projectMapper;

    @Override
    @Transactional
    public List<ProjectInfoVO> getProjectInfo() {
        List<ProjectInfoVO> projectInfo = projectMapper.getProjectInfo();
        if(projectInfo == null){
            return projectInfo;
        }
        projectInfo.forEach(pi->{
            if(pi.getContext() == null){
                pi.setContext(ProjectDetailConstant.THIS_PROJECT_IS_NOT_COMMENT);
            }
            pi.setSkuList(Arrays.stream(pi.getSku().split(",")).collect(Collectors.toList()));

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//            String nowDate = LocalDateTime.now().format(formatter);
            try {
                LocalDateTime createTime = LocalDateTime.parse(pi.getCreate_time(), formatter);
                LocalDateTime now = LocalDateTime.now();
                long sup = ChronoUnit.DAYS.between(createTime, now);
                if (sup >= pi.getTerm_day()) {
                    try {
                        projectMapper.updateProjectStatus(pi.getDe_id(), 6);
                        projectMapper.updateProjectPlan(pi.getDe_id(), 6);
                    } catch (Exception e) {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    }
                }
            } catch (Exception e) {
                throw new BaseException(MessageConstant.UNKNOWN_ERROR); //未知异常
            }

            /**
             * @龚英杰 20250324
             * SimpleDateFormat 非线程安全,已修改
             *SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
             *                 String nowDate = df.format(new Date());
             *                 try {
             *                     Date cT = df.parse(pi.getCreate_time());
             * //                        long sup = (df.parse(nowDate).getTime() - cT.getTime()) / 1000;
             *                     long sup = (df.parse(nowDate).getTime() - cT.getTime()) / 1000 / 60 / 60 / 24;
             *                     if(sup >= pi.getTerm_day()){
             *                         try{
             *                             projectMapper.updateProjectStatus(pi.getDe_id(),6);
             *                             projectMapper.updateProjectPlan(pi.getDe_id(),6);
             *                         }catch (Exception e){
             *                             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
             *                         }
             *                     }
             *                 } catch (ParseException e) {
             *                     throw new BaseException(MessageConstant.UNKNOWN_ERROR);//未知异常
             *                 }
             */
        });
        return projectInfo;
    }

    @Override
    public List<ProjectInfoVO> getProjectInfo(String tag) {
        List<ProjectInfoVO> projectInfo = projectMapper.getProjectInfoByTag(tag);
        if(projectInfo == null){
            return projectInfo;
        }
        projectInfo.forEach(pi->{
            if(pi.getContext() == null){
                pi.setContext(ProjectDetailConstant.THIS_PROJECT_IS_NOT_COMMENT);
            }
            pi.setSkuList(Arrays.stream(pi.getSku().split(",")).collect(Collectors.toList()));
        });
        return projectInfo;
    }

    @Async
    public void updateProjectStatusIfNeeded(ProjectDetailDTO projectDetail) {
        if (projectDetail.getStatus().equals(ProjectDetailConstant.IS_PROGRESS) || projectDetail.getStatus().equals(ProjectDetailConstant.PREPARATION_STAGE)) {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            String nowDate = df.format(new Date());
            try {
                Date cT = df.parse(projectDetail.getCreate_time());
                long sup = (df.parse(nowDate).getTime() - cT.getTime()) / 1000;
                if (sup < 0) {
                    try {
                        projectMapper.updateProjectStatus(projectDetail.getId(), 6);
                        projectMapper.updateProjectPlan(projectDetail.getId(), 6);
                        projectDetail.setStatus(ProjectDetailConstant.IS_CLOSED);
                        projectDetail.setPlan_id(5);
                    } catch (Exception e) {
                        // 如果更新失败，回滚事务
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    }
                }
            } catch (ParseException e) {
                throw new BaseException(MessageConstant.UNKNOWN_ERROR); // 未知错误
            }
        }
    }

    @Override
    @Transactional
    public ProjectDetailDTO getProjectDetailByID(HttpServletRequest request, Integer deid) {

        String token = request.getHeader(JwtHeaderConstant.TOKEN_NAME_LOWER);
        Integer userid;
        try {
            Claims claims = JwtUtil.parseJWT(token);
            userid = Integer.valueOf(claims.getSubject());
        } catch (Exception e) {
            throw new LoginFailedException(MessageConstant.LOGIN_INFORMATION_IS_INCORRECT); // 登录信息有误
        }

        ProjectDetailDTO projectDetail = projectMapper.getProjectDetail(deid);
        if (projectDetail != null) {
            // 异步处理状态更新的任务
            updateProjectStatusIfNeeded(projectDetail);

            // 判断当前用户是否是该项目的作者
            if (userid.equals(projectDetail.getAuthor_id())) {
                projectDetail.setPageStatus(true);
            } else {
                projectDetail.setPageStatus(false);
            }
        }
        return projectDetail;
    }

    @Override
    public List<PlansInfoDTO> getPlans() {
        return projectMapper.getPlans();
    }

    @Override
    public List<SkuInfoDTO> getSkus() {
        return projectMapper.getSkus();
    }

    @Override
    @Transactional
    public void saveProject(HttpServletRequest request,
                            ProjectSaveInfoDTO psi) {
        String token = request.getHeader(JwtHeaderConstant.TOKEN_NAME_LOWER);
        Integer userid;
        try {
            Claims claims = JwtUtil.parseJWT(token);
            userid = Integer.valueOf(claims.getSubject());
        } catch (Exception e) {
            throw new LoginFailedException(MessageConstant.LOGIN_INFORMATION_IS_INCORRECT);//登陆信息有误
        }
        psi.setAuthorId(userid);
        if(StringUtil.isNullOrEmpty(psi.getTitle()) || psi.getMoney() == 0){
            throw new ProjectDetailException(ProjectDetailConstant.TITLE_IS_NOT_NULL_AND_MONEY_IS_NOT_ZERO);//标题不能为空,金额不能为0
        }else{
            try{
                projectMapper.projectSave(psi,projectMapper);
            }catch (Exception e){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }
    }

    @Override
    @Transactional
    public void joinProject(JoinProjectInfoDTO jpi) {
        String token = jpi.getT();
        Integer userid;
        try {
            Claims claims = JwtUtil.parseJWT(token);
            userid = Integer.valueOf(claims.getSubject());
        } catch (Exception e) {
            throw new LoginFailedException(MessageConstant.LOGIN_INFORMATION_IS_INCORRECT);//登录信息有误
        }
        ProjectListDTO jp = projectMapper.showJoinProjectById(userid, jpi.getDeId());
        if(jp != null && jpi.getDeId().equals(jp.getDe_id()) && !jp.getStatus_id().equals(2)){
            throw new ProjectDetailException(ProjectWebStatusCodeConstant.CONFLICT_CODE,ProjectDetailConstant.REPEAT_JOINING);//重复加入
        }else{
            try{
                if(jp != null && jp.getStatus_id().equals(2)){
                    projectMapper.closeJoinProject(jp.getDui_id(),1);
                }else{
                    jpi.setUser_id(userid);
                    projectMapper.joinProject(jpi);
                    projectMapper.updatePerson(jpi.getDeId());
                    projectMapper.setDemandUserInfo(jpi.getDui_id());
                }
            }catch (Exception e){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                e.printStackTrace();
                throw new BaseException(MessageConstant.UNKNOWN_ERROR);//位置错误
            }
        }
    }

    @Override
    public List<ListPersonDTO> listJoinPerson(String token,Integer de_id) {
        Integer userid;
        try {
            Claims claims = JwtUtil.parseJWT(token);
            userid = Integer.valueOf(claims.getSubject());
        } catch (Exception e) {
            throw new LoginFailedException(MessageConstant.LOGIN_INFORMATION_IS_INCORRECT);//登录信息有误
        }

        List<ListPersonDTO> listPeople = projectMapper.listJoinPerson(de_id);

        listPeople.forEach(per->{
            if(per.getSkus() != null){
                List<String> perSkus = Arrays.stream(per.getSkus().split(",")).collect(Collectors.toList());
                per.setSkusList(perSkus);
            }
            if(userid.equals(per.getU_id())){
                per.setShow("true");
            }else{
                per.setShow("false");
            }
        });
        return listPeople;
    }

    @Override
    public void closeProject(HttpServletRequest request, Integer de_id) {
        String token = request.getHeader(JwtHeaderConstant.TOKEN_NAME_LOWER);
        Integer userid;
        try {
            Claims claims = JwtUtil.parseJWT(token);
            userid = Integer.valueOf(claims.getSubject());
        } catch (Exception e) {
            throw new LoginFailedException(MessageConstant.LOGIN_INFORMATION_IS_INCORRECT);//登录信息有误
        }

        Integer uid = projectMapper.showDemandIsWho(de_id);
        if(uid.equals(userid)){
            projectMapper.updateProjectStatus(de_id,2);
            projectMapper.updateProjectPlan(de_id,6);
        }
    }

    @Override
    @Transactional
    public void closeJoinProject(HttpServletRequest request, Object cj) {
        String token = request.getHeader(JwtHeaderConstant.TOKEN_NAME_LOWER);
        Integer userid;
        try {
            Claims claims = JwtUtil.parseJWT(token);
            userid = Integer.valueOf(claims.getSubject());
        } catch (Exception e) {
            throw new LoginFailedException(MessageConstant.LOGIN_INFORMATION_IS_INCORRECT);
        }

        JSONObject json = (JSONObject) JSONObject.toJSON(cj);
        JSONObject j1 = json.getJSONObject("cj");
        Integer uid = j1.getInteger("uid");
        Integer dui = j1.getInteger("dui");
        if(userid.equals(uid)){
            try{
                projectMapper.closeJoinProject(dui,2);
            }catch (Exception e){
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new BaseException(MessageConstant.UNKNOWN_ERROR);
            }
        }

    }

    @Override
    @Transactional
    public void isBid(HttpServletRequest request, Object obj) {
        try {
            String token = request.getHeader(JwtHeaderConstant.TOKEN_NAME_LOWER);
            Claims claims = JwtUtil.parseJWT(token);
            Integer.valueOf(claims.getSubject());
        } catch (Exception e) {
            throw new LoginFailedException(MessageConstant.LOGIN_INFORMATION_IS_INCORRECT);
        }

        try{
            JSONObject json = (JSONObject) JSONObject.toJSON(obj);
            JSONObject j_ob = json.getJSONObject("obj");
            Integer uid = j_ob.getInteger("u_id");
            Integer deid = j_ob.getInteger("de_id");
            projectMapper.isBid(uid,deid);
            projectMapper.updateProjectPlan(deid,3);
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new BaseException(MessageConstant.UNKNOWN_ERROR);
        }
    }


}
